package com.example.cinemaorder.consumer;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.example.cinemaorder.entity.SysBill;
import com.example.cinemaorder.entity.SysMovie;
import com.example.cinemaorder.entity.SysSession;
import com.example.cinemaorder.entity.vo.SearchMovieVo;
import com.example.cinemaorder.entity.vo.SysBillVo;
import com.example.cinemaorder.service.SysBillService;
import com.example.cinemaorder.service.SysSessionService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Insert;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 高垚淼
 * @version 1.0
 */
@Component
@Slf4j
public class GetOrderDeadDealConsumer {

    @Autowired
    SysBillService sysBillService;
    @Autowired
    SysSessionService sysSessionService;
    @Autowired
    RedisTemplate redisTemplate;

    @RabbitListener(queues = "getOrderDeadDeal")
    public void dealEmail(SysBillVo sysBillVo, Message message, Channel channel) throws IOException {
        try {
            log.info("进入死信队列");
            // 将原始数据查询出来
//            SysBill sysBill = sysBillService.getBillBySeats(sysBillVo.getSysBill().getSeats());
            SysBill sysBill = (SysBill) redisTemplate.opsForValue().get(sysBillVo.getSysBill().getSeats());
            Long billId = sysBill.getBillId();
            // 查询订单信息的，查询支付状态、查询取消状态
            SysBill timeoutBill = sysBillService.getBillById(billId);
            // 查询出排片信息
            SearchMovieVo curSession = sysBillService.getSessionById(sysBill.getSessionId());
            //如果未支付，则将取消状态设为1
            if(timeoutBill.getPayState() == 0 && timeoutBill.getCancelState() == 0){
                // 还原座位售出数量
                int updateSallNums = sysBill.getSeats().split(",").length;
                sysSessionService.updateSallNums(sysBill.getSessionId(),updateSallNums*(-1));
                // 取消锁座
                sysSessionService.updateCancelState(billId);
                // 获取当前超时订单座位信息
                String[] selectSeats = timeoutBill.getSeats().split(",");
                // 超时订单已选座位
                Map<String, Integer> selectedSeatsMap = new LinkedHashMap<>();
                for (int i = 0; i < selectSeats.length; i++) {
                    String row = selectSeats[i].substring(selectSeats[i].indexOf("\"") + 1, selectSeats[i].indexOf("排"));
                    Integer col = Integer.parseInt(selectSeats[i].substring(selectSeats[i].indexOf("排") + 1, selectSeats[i].indexOf("座")));
                    selectedSeatsMap.put(row, col);
                }
                // 取消场次座位占座
                String newSessionSeats = cancelTimeoutBillSessionSeats(curSession.getSessionSeats(), selectedSeatsMap);
                curSession.setSessionSeats(newSessionSeats);
                sysSessionService.updateSession(curSession);
            }

            //修改电影总票房
            if(timeoutBill.getPayState() == 1 && timeoutBill.getCancelState() == 0){
                //方法一：直接插入mysql数据库
//                Long movieId = sysSessionService.getMovieId(sysBill.getBillId());
//                sysSessionService.updateMovieSale(movieId, sysBill.getPrice());
                //方法二：存入redis,使用quartz定时框架每天将reids中的数据更新至数据库
                Long movieId = sysSessionService.getMovieId(sysBill.getBillId());
                redisTemplate.opsForValue().increment("电影票房："+movieId.toString(),sysBill.getPrice());
                //执行更新redis排行榜的操作
                double price = (double) redisTemplate.opsForValue().get("电影票房：" + movieId.toString());
                SysMovie sysMovie = (SysMovie) redisTemplate.opsForValue().get("电影排行榜：" + movieId);
                sysMovie.setMovieBoxOffice(price);
                redisTemplate.opsForValue().set("电影排行榜：" + movieId, sysMovie);
            }
        } catch (Exception e) {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }
    }

    public static String cancelTimeoutBillSessionSeats(String curSessionSeats, Map<String, Integer> selectedSeatsMap) {
        JSONObject curSessionSeatsJSON = JSONObject.parseObject(curSessionSeats);
        Map<String, Object> valueMap = new LinkedHashMap<>();
        valueMap.putAll(curSessionSeatsJSON);
        valueMap.forEach((key, value) -> System.out.println("\"" + key + "\":" + "   " + value));
        // 取消选座
        selectedSeatsMap.forEach((index, value) -> {
            ((JSONArray) valueMap.get(index)).set(value - 1, 0);
        });
        JSONObject newSessionSeatsJSON = new JSONObject(valueMap);
        return JSONObject.toJSONString(newSessionSeatsJSON);
    }
}
